#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <semaphore.h>
#include "ipc.h"
#include "main.h"
#include "util/log.h"

static pid_t client_pid = 0;

int ipc_start_server ()
{
	static const char* towerhackd = "./towerhackd";
	
	log_info ("Starting server.");
	
	sem_t* thsem = sem_open(SEMAPHORE_NAME, O_CREAT, 0600, 0);
	if (thsem == SEM_FAILED) {
		log_error ("Could not open semaphore \"%s\".\n", SEMAPHORE_NAME);
		return 0;
	}
	
	client_pid = fork ();
	if (client_pid < 0) {
		log_error ("Server start failed, errno = %d.", errno);
		return 0;
	} else if (client_pid == 0) {
		sem_close(thsem);
		execlp (towerhackd, towerhackd, NULL);
		exit (0);
	} else {
		struct timespec timeout;
		timeout.tv_sec = time (NULL) + SERVER_START_TIMEOUT;
		timeout.tv_nsec = 0;
		
		if (sem_timedwait(thsem, &timeout) != 0) {
			log_error ("Wait for server failed, errno = %d.", errno);
			sem_close(thsem);
			sem_unlink(SEMAPHORE_NAME);
			return 0;
		}
		log_info ("Server started, pid = %d.", client_pid);
		sem_close(thsem);
		sem_unlink(SEMAPHORE_NAME);
		return 1;
	}
}

void ipc_stop_server ()
{
	if (client_pid) {
		log_info ("Stopping server, pid %d.", client_pid);
		if (kill (client_pid, SIGINT) != 0) {
			log_error ("Failed to kill server process (errno %d).", errno);
		}
		client_pid = 0;
	}
}

void ipc_wake_client ()
{
	sem_t* thsem = sem_open(SEMAPHORE_NAME, 0);
	if (thsem != SEM_FAILED) {
		sem_post(thsem);
		sem_close(thsem);
		sem_unlink(SEMAPHORE_NAME);
	}
}
